#include "rtsp_proxy_server.h"
#include "event2/event.h"
#include "event2/listener.h"
#include <cstring>
#include "event2/bufferevent.h"
#include "play_connect_handler.h"
#include <unistd.h>
#include <iostream>
#include "thread_pool.h"

using namespace std;

RTSPProxyServer *RTSPProxyServer::NewCreate(unsigned short listener_port)
{
    return new RTSPProxyServer(listener_port);
}

void RTSPProxyServer::Connected(struct evconnlistener *listen, evutil_socket_t sock, struct sockaddr *addr, int len, void *ctx)
{
    char ip[16] = {0};
    sockaddr_in *addr_in = (sockaddr_in*)addr;
    evutil_inet_ntop(AF_INET, &addr_in->sin_addr, ip, sizeof(ip));
    qInfo("播放器 %s:%d 连接...", ip, addr_in->sin_port);
    RTSPProxyServer *self = (RTSPProxyServer*)ctx;
    PlayConnectHandler::NewCreate(self->event_base_, sock, ip, addr_in->sin_port);
}

bool RTSPProxyServer::Init()
{
    // 首先执行继承对象的初始化，如果失败直接返回不进入事件循环
    if(!ActionInit())
    {
        return false;
    }
    event_base_ = event_base_new();
    if(!event_base_)
    {
        return false;
    }
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(listener_port_);
    conn_listener_ = evconnlistener_new_bind(event_base_, Connected, this, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, this->backlog_, (sockaddr*)&sin, sizeof(sin));
    if(!conn_listener_)
    {
        return false;
    }
    qInfo("服务监听端口: %d", listener_port_);
    int thread_pool_size = Config::Get()->ThreadPoolSize();
    ThreadPool::Get()->Init(thread_pool_size);
    return true;
}

void RTSPProxyServer::Connect()
{
    while(!exit_loop_)
    {
        ActionLoop();
        event_base_loop(event_base_, EVLOOP_NONBLOCK);
        usleep(1000);
    }
    // 释放资源
    evconnlistener_free(conn_listener_);
    event_base_free(event_base_);
    conn_listener_ = NULL;
    event_base_ = NULL;
    ActionFree();
}

bool RTSPProxyServer::exit_loop() const
{
    return exit_loop_;
}

void RTSPProxyServer::set_exit_loop(bool is_loop)
{
    this->exit_loop_ = is_loop;
}

void RTSPProxyServer::ActionLoop()
{

}

bool RTSPProxyServer::ActionInit()
{
    return true;
}

void RTSPProxyServer::ActionFree()
{

}

RTSPProxyServer::~RTSPProxyServer()
{

}

RTSPProxyServer::RTSPProxyServer(unsigned short listener_port)
    : listener_port_(listener_port), backlog_(10), exit_loop_(false)
{
}

